/*
 * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>

/* Contrary to the ASan example, some UB checks require the optimizer to work. */
#if defined __clang__
#pragma clang optimize on
#elif defined(__GNUC__)
#pragma GCC optimize("Og")
#endif

#define PW_LOG_MODULE_NAME "test"
#include "pw_log/log.h"

static int foo(int *p) __attribute__((nonnull));

static int foo(int *p)
{
    int volatile x = 0;

    PW_LOG_INFO(" * Underflowing an int by subtraction");
    x = INT32_MIN;
    x = x - 1; // cppcheck-suppress integerOverflow

    PW_LOG_INFO(" * Overflowing an int by addition");
    x = INT32_MAX;
    x = x + 1; // cppcheck-suppress integerOverflow

    PW_LOG_INFO(" * Overflowing an int by multiplication");
    x *= INT32_MAX; // cppcheck-suppress integerOverflow

    PW_LOG_INFO(" * Dividing an integer by zero");
    return x / 0; // cppcheck-suppress zerodiv
}

int Test(void)
{
    PW_LOG_INFO(" * Passing null to non-null arg");
    foo(NULL);

    return 0;
}
